using System.Collections;
using DG.Tweening;
using GameFramework;
using ILRuntime.CLR.Method;
using ILRuntime.CLR.TypeSystem;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace StarForce
{
    /// <summary>
    /// 热更层UGUI界面
    /// </summary>
    public partial class HotfixUGuiForm : UGuiForm
    {
        /// <summary>
        /// 对应的热更新层UGUI界面类名
        /// </summary>
        [SerializeField] private string m_HotfixUGuiFormName;
        
        [SerializeField] private CusUIEffectType m_UIOpen = CusUIEffectType.None;
        [SerializeField] private CusUIEffectType m_UIClose = CusUIEffectType.None;
        /// <summary>
        /// 对应的热更新层实体逻辑类实例
        /// </summary>
        private object m_HotfixInstance;

        public object HotfixInstance
        {
            get { return m_HotfixInstance; }
            private set { m_HotfixInstance = value; }
        }

        //热更新层的方法缓存
        private ILInstanceMethod m_OnOpen;
        private ILInstanceMethod m_OnClose;
        private ILInstanceMethod m_OnPause;
        private ILInstanceMethod m_OnResume;
        private ILInstanceMethod m_OnCover;
        private ILInstanceMethod m_OnReveal;
        private ILInstanceMethod m_OnRefocus;
        private IMethod m_OnUpdate;
        private IMethod m_OnDepthChanged;

        /// <summary>
        /// 界面初始化（热更新层新增界面用）
        /// </summary>
        public void OnHotfixInit(string hotfixUGuiFormName, object userData = null)
        {
            if (string.IsNullOrEmpty(m_HotfixUGuiFormName))
            {
                m_HotfixUGuiFormName = hotfixUGuiFormName;
                OnInit(userData);
                OnOpen(userData);
                UIForm.Logic = this;
                GameEntry.UI.RefocusUIForm(UIForm);
            }
        }

        protected override void OnInit(object userData)
        {
            base.OnInit(userData);

            string hotfixUGuiFormFullName =
                Utility.Text.Format("{0}.Hotfix.{1}", Constant.AssemblyInfo.Namespace, m_HotfixUGuiFormName);
            
            //获取热更新层的实例
//            foreach (KeyValuePair<string,IType> appDomainLoadedType in GameEntry.ILRuntime.AppDomain.LoadedTypes)
//            {
//                Log.Info("string:"+appDomainLoadedType.Key);
//                Log.Info("IType:"+appDomainLoadedType.Value);
//            }
            IType type = GameEntry.ILRuntime.AppDomain.LoadedTypes[hotfixUGuiFormFullName];
            m_HotfixInstance = ((ILType) type).Instantiate();
            //获取热更新层的方法并缓存
            m_OnOpen = new ILInstanceMethod(m_HotfixInstance, hotfixUGuiFormFullName, "OnOpen", 1);
            m_OnClose = new ILInstanceMethod(m_HotfixInstance, hotfixUGuiFormFullName, "OnClose", 2);
            m_OnPause = new ILInstanceMethod(m_HotfixInstance, hotfixUGuiFormFullName, "OnPause", 0);
            m_OnResume = new ILInstanceMethod(m_HotfixInstance, hotfixUGuiFormFullName, "OnResume", 0);
            m_OnCover = new ILInstanceMethod(m_HotfixInstance, hotfixUGuiFormFullName, "OnCover", 0);
            m_OnReveal = new ILInstanceMethod(m_HotfixInstance, hotfixUGuiFormFullName, "OnReveal", 0);
            m_OnRefocus = new ILInstanceMethod(m_HotfixInstance, hotfixUGuiFormFullName, "OnRefocus", 1);
            m_OnUpdate = type.GetMethod("OnUpdate", 2);
            m_OnDepthChanged = type.GetMethod("OnDepthChanged", 2);

            //调用热更新层的OnInit
            GameEntry.ILRuntime.AppDomain.Invoke(hotfixUGuiFormFullName, "OnInit", m_HotfixInstance, this, userData);
        }

        protected override void OnOpen(object userData)
        {
            base.OnOpen(userData);

            m_OnOpen?.Invoke(userData);
        }

        protected override void OnClose(bool isShutdown, object userData)
        {
            base.OnClose(isShutdown, userData);
//            if (m_UIClose == CusUIEffectType.None)
//            {
//                base.Close();
//            }
//            else
//            {
//                switch (m_UIClose)
//                {
//                    case CusUIEffectType.Fade : 
//                        StartCoroutine(CloseCo(0.5f));
//                        break;
//                    case CusUIEffectType.Zoom : Zoom(false);
//                        break;
//                }
//            }
            m_OnClose?.Invoke(isShutdown, userData);
        }

        protected override void OnPause()
        {
            base.OnPause();

            m_OnPause?.Invoke();
        }

        protected override void OnResume()
        {
            base.OnResume();

            m_OnResume?.Invoke();
        }

        protected override void OnCover()
        {
            base.OnCover();

            m_OnCover?.Invoke();
        }

        protected override void OnReveal()
        {
            base.OnReveal();

            m_OnReveal?.Invoke();
        }

        protected override void OnRefocus(object userData)
        {
            base.OnRefocus(userData);

            m_OnRefocus?.Invoke(userData);
        }

        protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(elapseSeconds, realElapseSeconds);

            using (var ctx = GameEntry.ILRuntime.AppDomain.BeginInvoke(m_OnUpdate))
            {
                ctx.PushObject(m_HotfixInstance);
                ctx.PushFloat(elapseSeconds);
                ctx.PushFloat(realElapseSeconds);
                ctx.Invoke();
            }
        }

        protected override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
        {
            base.OnDepthChanged(uiGroupDepth, depthInUIGroup);

            using (var ctx = GameEntry.ILRuntime.AppDomain.BeginInvoke(m_OnDepthChanged))
            {
                ctx.PushObject(m_HotfixInstance);
                ctx.PushInteger(uiGroupDepth);
                ctx.PushInteger(depthInUIGroup);
                ctx.Invoke();
            }
        }

        protected virtual void UIShow(bool isOpen)
        {
            CanvasGroup.alpha = 1;
            
            if (!isOpen)
            {
                GameEntry.UI.CloseUIForm(this);
            }
            else
            {
                // if (transform.GetChild(1).name == "Panel")
                // {
                //     transform.GetChild(1).localScale = new Vector3(0.5f, 0.5f, 0.5f);
                //     transform.GetChild(1).DOScale(new Vector3(1.05f, 1.05f, 1), 0.3f).SetEase(Ease.InOutBack).OnComplete(() =>
                //     {
                //         transform.GetChild(1).DOScale(new Vector3(1f, 1f, 1), 0.2f).SetEase(Ease.InOutBounce);
                //     });
                //     
                //     return;
                // }

                transform.localScale = new Vector3(1.03f, 1.03f, 1.03f);
                transform.DOScale(new Vector3(1f, 1f, 1), 0.2f).SetEase(Ease.InOutBack);
                //     .OnComplete(() =>
                // {
                //     transform.DOScale(new Vector3(1f, 1f, 1), 0.2f).SetEase(Ease.Linear);
                // });
            }
        }

        protected virtual void Zoom(bool isOpen)
        {
            CanvasGroup.alpha = 1;
            Vector3 endScale = new Vector3(0.3f, 0.3f, 0.3f);
            if (!isOpen)
            {
                transform.DOScale(endScale, 0.3f).SetEase(Ease.Linear).OnComplete(() =>
                {
                    GameEntry.UI.CloseUIForm(this);
                });
            }
            else
            {
                if (transform.GetChild(1).name == "Panel")
                {
                    transform.GetChild(1).localScale = new Vector3(0.5f, 0.5f, 0.5f);
                    transform.GetChild(1).DOScale(new Vector3(1.05f, 1.05f, 1), 0.3f).SetEase(Ease.InOutBack).OnComplete(() =>
                    {
                        transform.GetChild(1).DOScale(new Vector3(1f, 1f, 1), 0.2f).SetEase(Ease.InOutBounce);
                    });
                    
                    return;
                }

                transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
                transform.DOScale(new Vector3(1.1f, 1.1f, 1), 0.3f).SetEase(Ease.InOutBack).OnComplete(() =>
                {
                    transform.DOScale(new Vector3(1f, 1f, 1), 0.2f).SetEase(Ease.Linear);
                });
            }
        }

        protected virtual void None(bool isOpen)
        {
            if (isOpen)
            {
                CanvasGroup.alpha = 1;
            }
            else
            {
                GameEntry.UI.CloseUIForm(this);
            }
        }

        protected virtual void Fade(bool isOpen)
        {
            if (isOpen)
            {
                CanvasGroup.alpha = 0;
                DOTween.To(() => CanvasGroup.alpha, x => CanvasGroup.alpha = x,  1 , 1);
            }
            else
            {
                DOTween.To(() => CanvasGroup.alpha, x => CanvasGroup.alpha = x,  0, 1).OnComplete((() => GameEntry.UI.CloseUIForm(this)));
            }
           
            // StartCoroutine(CanvasGroup.FadeToAlpha(1, 1f));
        }

        public override void Close()
        {
            StopAllCoroutines();
            switch (m_UIClose)
            {
                case CusUIEffectType.None:
                    None(false);
                    break;
                case CusUIEffectType.Zoom:
                    Zoom(false);
                    break;
                case CusUIEffectType.Fade:
                    Fade(false);
                    break;
            }
        }
    }
}